import piexif from 'piexifjs'

/** 可以将字节数转换为可读性更好的存储单位 */
export function formatBytes(bytes: number): string {
    if (bytes < 1024) {
        return bytes + ' bytes';
    } else if (bytes < 1024 * 1024) {
        return (bytes / 1024).toFixed(2) + ' KB';
    } else if (bytes < 1024 * 1024 * 1024) {
        return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
    } else {
        return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
    }
}

export function getVideoResolution(url: string): Promise<{ width: number; height: number; }> {
    // 创建video元素
    let video = document.createElement('video')
    // 设置视频网络地址
    video.src = url
    return new Promise((resovle) => {
        // 监听loadedmetadata事件
        video.addEventListener('loadedmetadata', function () {
            // 获取视频宽度和高度
            let width = video.videoWidth
            let height = video.videoHeight
            // 调用回调函数并传递分辨率
            resovle({ width, height })
        })
    })
}

/** 返回类似“刚刚”、“1分钟前”等相对时间 */
export function timeAgo(dateString: any): string {
    const now: any = new Date()
    const date: any = new Date(dateString.replace(' ', 'T')) // 转换为 ISO 格式

    const diff = now - date
    const seconds = Math.floor(diff / 1000)
    const minutes = Math.floor(seconds / 60)
    const hours = Math.floor(minutes / 60)
    const days = Math.floor(hours / 24)

    if (days > 0) {
        return days + (days === 1 ? '天前' : '天前')
    }
    if (hours > 0) {
        return hours + (hours === 1 ? '小时前' : '小时前')
    }
    if (minutes > 0) {
        return minutes + (minutes === 1 ? '分钟前' : '分钟前')
    }
    if (seconds > 0) {
        return '刚刚'
    }
    return '刚刚' // 如果差异很小（例如0秒），默认返回“刚刚”
}

/** 将时间戳转换为 2024-08-13 11:30:08 格式 */
export function formatTimestamp(timestamp: number): string {
    // 转换为毫秒级时间戳
    const date = new Date(timestamp * 1000);

    // 获取年、月、日、时、分、秒
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');

    // 格式化为 "YYYY-MM-DD HH:MM:SS"
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

/** 将字符串首字母大写 */
export function capitalizeFirstLetter(string: string): string {
    if (typeof string !== 'string' || string.length === 0) return string;
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// 根据当前时间返回 "1970-01-01 00:00:00" 格式的日期时间字符串
export function getCurrentDateTime() {
    const now = new Date()
    const year = now.getFullYear()
    const month = String(now.getMonth() + 1).padStart(2, '0')
    const day = String(now.getDate()).padStart(2, '0')
    const hours = String(now.getHours()).padStart(2, '0')
    const minutes = String(now.getMinutes()).padStart(2, '0')
    const seconds = String(now.getSeconds()).padStart(2, '0')
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

/** 函数将接受两个日期字符串和一个分钟数，判断两个时间之间的差异是否超过指定的分钟数，并返回相应的布尔值 */
export function areTimesWithinNMinutes(time1: string, time2: string, n: number): boolean {
    // 将日期字符串转换为 Date 对象
    const date1: any = new Date(time1.replace(/-/g, '/'));
    const date2: any = new Date(time2.replace(/-/g, '/'));

    // 计算两个日期之间的差值（毫秒）
    const differenceInMillis = Math.abs(date2 - date1);

    // 转换分钟数为毫秒
    const nMinutesInMillis = n * 60 * 1000;

    // 判断差值是否超过指定的分钟数
    return differenceInMillis <= nMinutesInMillis;
}

export function getFileNameFromUrl(url: string): string {
    return url.substring(url.lastIndexOf('/') + 1)
}

/** 传入一个url，下载文件 */

/**
 * @export
 * @param {string} url 文件路径
 * @param {string} fileName 下载的文件名称
 */
export function downloadFile(url: string, fileName: string): void {
    fetch(url)
        .then(response => response.blob())
        .then(blob => {
            const blobUrl = window.URL.createObjectURL(blob)
            const a = document.createElement('a')
            a.href = blobUrl
            // 获取文件名
            a.download = fileName
            document.body.appendChild(a)
            a.click()
            setTimeout(() => {
                document.body.removeChild(a)
                window.URL.revokeObjectURL(blobUrl)
            }, 0)
        })
        .catch(error => console.error('Error downloading file:', error))
}

export async function chunkUplaod(baseUrl: string, fileName: string, cb: any) {
    const calculatePercentage = (start: any, end: any) => {
        if (end === 0) {
            throw new Error('The end value cannot be zero.')
        }
        return ((start / end) * 100).toFixed(2) // 返回百分比，保留两位小数
    }

    const getFileSize = async (url: any) => {
        try {
            const response = await fetch(url, {
                method: 'HEAD' // 使用 HEAD 请求只获取头部信息，不下载文件内容
            });

            if (response.ok) {
                const contentLength = response.headers.get('Content-Length')
                if (contentLength) {
                    return parseInt(contentLength, 10); // 返回文件大小（字节）
                } else {
                    throw new Error('Content-Length header is not present')
                }
            } else {
                throw new Error('Failed to fetch file size')
            }
        } catch (error) {
            console.error('Error:', error)
            return null
        }
    }

    const chunkSize = 1024 * 1024 // 每个分片的大小（1MB）
    let start = 0
    let end = chunkSize

    const fileSize = await getFileSize(baseUrl)

    const downloadChunk = async (start: any, end: any) => {
        const response = await fetch(baseUrl, {
            headers: {
                'Range': `bytes=${start}-${end - 1}`
            }
        })
        if (!response.ok) throw new Error('Network response was not ok.')
        return response.blob()
    };

    const downloadFile = async () => {
        let fileBlob = new Blob([])
        while (true) {
            try {
                const chunkBlob = await downloadChunk(start, end)
                fileBlob = new Blob([fileBlob, chunkBlob])
                start = end
                end = start + chunkSize
                cb(calculatePercentage(end, fileSize))
            } catch (error) {
                console.error('Download error:', error)
                break
            }
        }

        const url = URL.createObjectURL(fileBlob)
        const a = document.createElement('a')
        a.href = url
        a.download = fileName
        document.body.appendChild(a)
        a.click()
        URL.revokeObjectURL(url)
    }
    downloadFile()
}

/** 获取图片dpi */
export function getFileDpi(file: File) {
    if (!file) return Promise.reject('error')
    return new Promise((resovle, reject) => {
        const reader = new FileReader();
        reader.onload = (e: ProgressEvent<FileReader>) => {
            const binaryString = e.target?.result
            try {
                resovle(piexif.load(binaryString))
            } catch (error) {
                resovle(72)
            }
        }
        reader.readAsDataURL(file)
    })
}

export function replaceCommaWithDash(input: string | undefined): string | undefined {
    if (!input) return
    return input.replace(/,/g, '-');
}

/** url转换未blob */
export async function urlToFile(url: any, filename: any) {
    const response = await fetch(url);
    const blob = await response.blob();
    const file = new File([blob], filename, { type: blob.type })

    return URL.createObjectURL(file)
}